package ding.utils;


import javafx.util.Pair;
import org.apache.poi.ss.usermodel.*;

import java.io.File;
import java.io.FileInputStream;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Map;

//将一个表格文件读取成一个map
public class ExcelUtils {


    public interface ValueMaker {
        String value(Cell o);
    }

    public interface NameMaker {
        String name(Cell o);
    }

    public interface NameValueMaker extends ValueMaker, NameMaker {

    }


    public interface CannotMappingHandler {
        Pair handle(Cell name, Cell value);
    }

    //该方法用于将对象
    public static Map<String, String> transform(File file, String user, Map<String, NameValueMaker> mapping, CannotMappingHandler cannotMappingHandler) {

        Map<String, String> r = new HashMap<>();

        try {

            Workbook sheets = WorkbookFactory.create(new FileInputStream(file));

            Sheet rows = sheets.getSheet("Sheet1");
            if (rows != null) {

                NameRow indexRow = findIndexRow(rows);

                if (indexRow == null) {
                    r.put("__ERROR_TYPE__", "没有索引行");
                    return r;
                }

                int index = indexRow.index;

                Row names = indexRow.row;

                Row values = findUserRow(rows, index, indexRow.rowNumber+1, user);

                if (values == null) {
                    r.put("__ERROR_TYPE__", "未找到记录");
                    return r;
                }

                for (int i = names.getFirstCellNum(); i < names.getLastCellNum(); i++) {
                    Cell name = names.getCell(i);

                    if (name == null) {
                        continue;
                    }

                    try {
                        Cell cell = values.getCell(i);
                        NameValueMaker nameValue = mapping.get(name.toString());

                        if (nameValue == null) {
                            Pair<String, String> pair = cannotMappingHandler.handle(name, cell);
                            if (pair != null) {
                                r.put(pair.getKey(), pair.getValue());
                            }
                        } else {
                            String value = nameValue.value(cell);
                            String n = nameValue.name(name);
                            if (n != null) {
                                if (value != null && !value.equals("")) {
                                    r.put(n, value);
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }


            }
        } catch (Exception e) {

            r.put("__ERROR_TYPE__", "处理Excel文件时出错");
            return r;

        }


        return r;

    }


    private static NameRow findIndexRow(Sheet rows) {
        for (int i = rows.getFirstRowNum(); i < rows.getLastRowNum(); i++) {
            Row row = rows.getRow(i);
            if (row == null) {
                continue;
            }
            for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
                Cell cell = row.getCell(j);
                if (cell == null) {
                    continue;
                }
                if (cell.toString().equals("姓名")) {
                    NameRow nameRow = new NameRow();
                    nameRow.row = row;
                    nameRow.index = j;
                    nameRow.rowNumber = i;//所在行
                    return nameRow;
                }
            }

        }
        return null;
    }

    private static Row findUserRow(Sheet rows, int index, int f, String user) {


        int to = rows.getLastRowNum();


        //这里的名称算法存在问题
        for (int i = f; i < to + 1; i++) {

            Row row = rows.getRow(i);
            if (row == null) {
                continue;
            }
            Cell cell = row.getCell(index);
            if (cell == null) {
                continue;
            }
            if (cell.getCellType() == CellType.STRING) {


                //将字符串处理
                String value = cell.getStringCellValue();

                String[] split = value.split(" ");

                StringBuilder builder = new StringBuilder();

                for (String s : split) {
                    builder.append(s);
                }

                //返回当前行
                if (builder.toString().equals(user)) {
                    return row;
                }

            }
        }

        return null;
    }

    private static class NameRow {
        Row row;
        int index;
        int rowNumber;
    }

    public static class MappingBuilder {


        private Map<String, NameValueMaker> nameValueMap = new HashMap<>();

        private static NumberFormat nf = NumberFormat.getInstance();


        public void autoMap(String name, final String toName) {
            nameValueMap.put(name, new NameValueMaker() {
                public String name(Cell o) {
                    return toName;
                }

                public String value(Cell o) {

                    if (o == null) {
                        return null;
                    }
                    if (o.getCellType() == CellType.STRING) {
                        return o.getStringCellValue();
                    } else if (o.getCellType() == CellType.NUMERIC) {
                        return nf.format(o.getNumericCellValue());
                    } else if (o.getCellType() == CellType.BLANK) {
                        return "";
                    }

                    return null;
                }
            });
        }

        public void map(String name, final String toName, final ValueMaker valueMaker) {
            nameValueMap.put(name, new NameValueMaker() {
                public String name(Cell o) {
                    return toName;
                }

                public String value(Cell o) {
                    return valueMaker.value(o);
                }
            });
        }

        public Map<String, NameValueMaker> build() {
            return nameValueMap;
        }
    }

}
